package com.lj.job.utils;

import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.lj.job.entity.JobLog;
import com.lj.job.entity.ScheduleJob;
import com.lj.job.service.JobLogService;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobExecutionContext;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.scheduling.quartz.QuartzJobBean;

/**
 * @author luojing
 * @since 2025/3/20 15:34
 * 定时任务执行的代理类，由它来找到真实的执行bean,并记录日志
 */
@Slf4j
public class JobProxy extends QuartzJobBean {

    /**
     * 调度任务的key
     */
    public static final String SCHEDULE_JOB_KEY = "SCHEDULE_JOB_KEY";

    /**
     * 任务日志类，不必每个任务都去拿一次
     */
    private static final JobLogService jobLogService = SpringUtil.getBean(JobLogService.class);

    @Override
    protected void executeInternal(JobExecutionContext context) {
        ScheduleJob scheduleJob = (ScheduleJob) context.getMergedJobDataMap()
                .get(SCHEDULE_JOB_KEY);

        // 获取真实要执行的类
        ITask target;
        try {
            target = SpringUtil.getBean(scheduleJob.getBeanName(), ITask.class);
        } catch (NoSuchBeanDefinitionException e) {
            log.warn("定时任务: 无法找到名称为:[{}] 的spring bean 无法执行！", scheduleJob.getBeanName());
            return;
        }

        JobLog jobLog = new JobLog();
        jobLog.setJobId(scheduleJob.getId());
        jobLog.setBeanName(scheduleJob.getBeanName());
        jobLog.setParams(scheduleJob.getParams());

        long startTime = System.currentTimeMillis();

        try {
            //执行任务
            target.run(scheduleJob.getParams());

            //任务执行总时长
            jobLog.setTimes((int) (System.currentTimeMillis() - startTime));
            // 任务执行成功
            jobLog.setSucceed(true);
        } catch (Exception e) {
            //任务执行总时长
            jobLog.setTimes((int) (System.currentTimeMillis() - startTime));
            // 任务执行失败
            jobLog.setSucceed(false);
            jobLog.setError(StrUtil.sub(e.toString(), 0, 200));
        } finally {
            jobLogService.save(jobLog);
        }

    }
}
